package com.simplesoft.accountbook;

import java.util.Calendar;
import java.util.Formatter;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class Summary extends Activity implements OnClickListener, OnTouchListener {
	private Calendar displayDate = Calendar.getInstance();
	private Dialog dialog_addRecord = null;
	Dialog dialog_about = null;
	private SimpleCursorAdapter adapter = null;
	private String listDataKey[] = new String[] {
		"rid", "day", "amount"
	};
	private int listDataTo[] = null;
	private float lastX;
	private float lastY;
	private static final int ACTION_NONE = 0;
	private static final int ACTION_FLIPPING = 1;
	private int action = ACTION_NONE;
	private float MIN_TOUCH_SLOP = 0;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.summary);
        ((Button)findViewById(R.id.btn_nextMonth)).setOnClickListener(this);
        ((Button)findViewById(R.id.btn_prevMonth)).setOnClickListener(this);
        ((Button)findViewById(R.id.btn_add)).setOnClickListener(this);
        ((TextView)findViewById(R.id.text_thisMonth)).setOnClickListener(this);
        registerForContextMenu(findViewById(R.id.listview_records));
        this.MIN_TOUCH_SLOP = ViewConfiguration.get(this).getScaledTouchSlop();
        // ListView
        ListView lv = (ListView)findViewById(R.id.listview_records);
        lv.setOnTouchListener(this);
        listDataTo = new int[] {
        		R.id.textview_recordid,
        		R.id.textview_record_date,
        		R.id.textview_record_amount};
        updateDisplayDate();
        updateSummery();
    }

	@Override
	protected void onRestart() {
		super.onRestart();
		this.displayDate = Calendar.getInstance();
		updateDisplayDate();
		updateSummery();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater mf = new MenuInflater(this);
		mf.inflate(R.menu.summary, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_settings:
			this.startActivity(new Intent(this, com.simplesoft.accountbook.Settings.class));
			return true;
		case R.id.menu_about:
			openAboutDialog();
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}
	
	private void openNewRecordDialog () {
		if (this.dialog_addRecord == null) {
			this.dialog_addRecord = new Dialog(this);
			this.dialog_addRecord.setContentView(R.layout.new_record);
			this.dialog_addRecord.setTitle(R.string.btn_add);
			Button btn_yes = (Button)this.dialog_addRecord.findViewById(R.id.btn_addRecordYes);
			Button btn_no = (Button)this.dialog_addRecord.findViewById(R.id.btn_addRecordNo);
			btn_yes.setOnClickListener(this);
			btn_no.setOnClickListener(this);
		}
		DatePicker dp = (DatePicker)this.dialog_addRecord.findViewById(R.id.datepicker_today);
		EditText v = (EditText)this.dialog_addRecord.findViewById(R.id.edittext_amount);
		dp.updateDate(
				this.displayDate.get(Calendar.YEAR),
				this.displayDate.get(Calendar.MONTH),
				this.displayDate.get(Calendar.DAY_OF_MONTH)
				);
		v.setText("");
		this.dialog_addRecord.show();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_addRecordYes:
			this.dialog_addRecord.dismiss();
			DatePicker dp = (DatePicker)this.dialog_addRecord.findViewById(R.id.datepicker_today);
			EditText et = (EditText)this.dialog_addRecord.findViewById(R.id.edittext_amount);
			if (et.getText().length() == 0) {
				Toast.makeText(this, getText(R.string.str_amount_is_not_inputed), Toast.LENGTH_SHORT).show();
			} else {
				insertNewRecord(dp.getYear(), dp.getMonth(), dp.getDayOfMonth(), et.getText().toString());
			}
			break;
		case R.id.btn_addRecordNo:
			this.dialog_addRecord.dismiss();
			break;
		case R.id.btn_nextMonth:
			this.displayDate.add(Calendar.MONTH, 1);
			updateDisplayDate();
			updateSummery();
			break;
		case R.id.btn_prevMonth:
			this.displayDate.add(Calendar.MONTH, -1);
			updateDisplayDate();
			updateSummery();
			break;
		case R.id.text_thisMonth:
			this.displayDate = Calendar.getInstance();
			updateDisplayDate();
			updateSummery();
			Toast.makeText(this, getText(R.string.str_returned_to_this_month), Toast.LENGTH_SHORT).show();
			break;
		case R.id.btn_about_dismiss:
			this.dialog_about.dismiss();
			break;
		case R.id.btn_add:
			openNewRecordDialog();
			break;
		}
	}
	
	private void updateDisplayDate () {
		Formatter f = new Formatter();
		f.format("%04d-%02d", 
				this.displayDate.get(Calendar.YEAR), 
				this.displayDate.get(Calendar.MONTH) + 1);
		((TextView)findViewById(R.id.text_thisMonth)).setText(f.toString());
	}
	
	private void insertNewRecord (int year, int month, int day_of_month, String amount) {
		MyDatabaseOpenHelper helper = new MyDatabaseOpenHelper(this);
		SQLiteDatabase mydb = helper.getWritableDatabase();
		mydb.execSQL("INSERT INTO money_record (year, month, day, amount) values (" +
				year + ", " + 
				month + ", " + 
				day_of_month + ", " + 
				amount + ");");
		mydb.close();
		updateSummery();
		Toast.makeText(this, getString(R.string.str_one_record_is_added), Toast.LENGTH_SHORT).show();
	}
	
	private void updateSummery () {
		String year = Integer.toString(this.displayDate.get(Calendar.YEAR));
		String month = Integer.toString(this.displayDate.get(Calendar.MONTH));
		MyDatabaseOpenHelper helper = new MyDatabaseOpenHelper(this);
		SQLiteDatabase mydb = helper.getReadableDatabase();
		Cursor cr = null;
		
		// query sum
		cr = mydb.query(
				"money_record", 
				new String[] {
						"total(amount)"
				}, 
				"year = ? and month = ?", 
				new String[] {
					year,
					month
				}, 
				null, 
				null,
				null);
		cr.moveToFirst();
		TextView summery_total = (TextView)findViewById(R.id.text_total_value);
		summery_total.setText(Float.toString(cr.getFloat(0)));
		cr.close();
		
		cr = mydb.query("money_record", 
				new String[] {
						"rid as _id", 
						"rid", 
						"day",
						"amount"}, 	
				"year = ? and month = ?", 
				new String[] {
						year, 
						month}, 
				null, 
				null, 
				"day desc, rid desc");
		 adapter = new SimpleCursorAdapter(
				 this,
				 R.layout.summary_record,
				 cr,
				 listDataKey,
				 listDataTo);
		 ListView lv = (ListView)findViewById(R.id.listview_records);
		 lv.setAdapter(adapter);
		 mydb.close();
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		MenuInflater mf = new MenuInflater(this);
		mf.inflate(R.menu.list_context_menu, menu);
	}	

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.cmenu_del:
			AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
			TextView rid = (TextView)acmi.targetView.findViewById(R.id.textview_recordid);
			MyDatabaseOpenHelper helper = new MyDatabaseOpenHelper(this);
			SQLiteDatabase mydb = helper.getWritableDatabase();
			mydb.execSQL("DELETE FROM money_record WHERE rid = " + rid.getText() + ";");
			mydb.close();
			updateSummery();
			Toast.makeText(this, getString(R.string.str_one_record_is_deleted), Toast.LENGTH_SHORT).show();
			break;
		}
		return true;
	}

	private void openAboutDialog () {
		if (this.dialog_about == null) {
			this.dialog_about = new Dialog(this);
			this.dialog_about.setContentView(R.layout.about);
			this.dialog_about.setTitle(R.string.menu_about);
			WebView view = (WebView)this.dialog_about.findViewById(R.id.webview_about);
			view.loadUrl("file:///android_asset/about.html");
			Button dismiss = (Button)this.dialog_about.findViewById(R.id.btn_about_dismiss);
			dismiss.setOnClickListener(this);
		}
		this.dialog_about.show();
	}

	@Override
	public boolean onTouch(View v, MotionEvent ev) {
		int act = ev.getAction();
		
		if (this.action == ACTION_FLIPPING && ev.getAction() == MotionEvent.ACTION_MOVE) {
			// Since one ACTION_MOVE event is received, discard others.
			return true;
		}
		
		switch (act) {
		case MotionEvent.ACTION_MOVE:
				float diffX = this.lastX - ev.getX();
				float diffY = this.lastY - ev.getY();
				
				if (Math.abs(diffX) < MIN_TOUCH_SLOP || Math.abs(diffY) >= MIN_TOUCH_SLOP) {
					return super.onTouchEvent(ev);
				} else {
					this.action = ACTION_FLIPPING;
				}
				
				if (diffX > 0) {
					this.displayDate.add(Calendar.MONTH, 1);
					updateDisplayDate();
					updateSummery();
				} else if (diffX < 0){
					this.displayDate.add(Calendar.MONTH, -1);
					updateDisplayDate();
					updateSummery();
				}
				
				MotionEvent me = MotionEvent.obtain(ev);
				me.setAction(MotionEvent.ACTION_CANCEL);
				v.dispatchTouchEvent(me);
				return true;
		case MotionEvent.ACTION_DOWN:
			this.lastX = ev.getX();
			this.lastY = ev.getY();
		case MotionEvent.ACTION_UP:
			this.action = ACTION_NONE;
		default:
			return super.onTouchEvent(ev);
		}
	}
}